#include"include/lyric.h"

Lyrics::Lyrics(const QString &fileName)
{
    pos=0;
    timeStamps=QList<qint64>();
    lyrics=QStringList();
    QFile file(fileName);
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
        return;
    QTextStream in(&file);
    while(!in.atEnd())
        oriLyrics<< in.readLine();
    file.close();

    lyricInfo<<QObject::tr("Title:").append(getLrcInfo("ti"));
    lyricInfo<<QObject::tr("Artist:").append(getLrcInfo("ar"));
    lyricInfo<<QObject::tr("Album:").append(getLrcInfo("al"));
    lyricInfo<<QObject::tr("By:").append(getLrcInfo("by"));
    QString offset_str=getLrcInfo("offset");
    if(offset_str.isEmpty())
        offset=0;
    else
        offset=offset_str.toInt();

    parseOriLyrics();
}

Lyrics::Lyrics(const QString &str,QString splitter)
{
    pos=0;
    oriLyrics=str.split(splitter);

    lyricInfo<<QObject::tr("Title:").append(getLrcInfo("ti"));
    lyricInfo<<QObject::tr("Artist:").append(getLrcInfo("ar"));
    lyricInfo<<QObject::tr("Album:").append(getLrcInfo("al"));
    lyricInfo<<QObject::tr("By:").append(getLrcInfo("by"));
    QString offset_str=getLrcInfo("offset");
    if(offset_str.isEmpty())
        offset=0;
    else
        offset=offset_str.toInt();

    parseOriLyrics();
}

QString Lyrics::getLrcInfo(const QString &tag)
{
    foreach(QString line, oriLyrics)
    {
        QRegExp rx("\\["+tag+":(.*)\\]");
        if(rx.indexIn(line, 0) != -1)
            return rx.cap(1);
    }
    return QString();
}

void Lyrics::parseOriLyrics()
{
    QMap<qint64,QString> lrc;
    QList<qint64> time0;
    QString line;
    QRegExp rxLine("^(\\[\\d{2}:\\d{2}(\\.\\d{2})?\\])+(.*)$");
    QRegExp rxTime("\\[(\\d{2}):(\\d{2})(\\.(\\d{2}))?\\]");
    rxLine.setMinimal(true);
    foreach(line, oriLyrics)
    {
        time0.clear();
        if(rxLine.indexIn(line, 0) != -1)
        {
            QString matchedStr = rxLine.cap(0);
            while(rxTime.indexIn(matchedStr, 0) != -1)
            {
                matchedStr.remove(0, rxTime.matchedLength());       //remove string as [*]
                int time=rxTime.cap(1).toUInt()*60000u+ rxTime.cap(2).toUInt()*1000u+rxTime.cap(4).toUInt()*10u;
                time0.append(time);
            }
            for(int i=0;i<time0.size();i++)
            {
                lrc.insert(time0[i],matchedStr);
            }
        }
    }
    timeStamps<<lrc.keys();
    if(timeStamps.isEmpty())
        timeStamps<<0;              //at least one.for lyrics not correct
    lyrics<<lrc.values();
    if(lyrics.isEmpty())
        lyrics<<QString();          //at least one.for lyrics not correct
}

QString Lyrics::getLyrics(qint64 t)
{
    int count=timeStamps.size()-1;
    if(t<timeStamps[0])
        return QString("Music...");
    for(int i=0;i<count+1;i++)
    {
        if(t>timeStamps[pos]&&pos<count&&t<timeStamps[pos+1])
            return lyrics[pos];
        else if(pos<count&&t>timeStamps[pos+1])
            ++pos;
        else if(pos>0&&t<timeStamps[pos-1])
            --pos;
    }
    return lyrics.last();
}
